/* -*- mode: c++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- */

#ifndef _DYBUF_H_
#define _DYBUF_H_

class DyBuf {
public:
    char               *buf;

    int                 buf_size;

    int                 buf_left;

    int                 buf_right;

    /* 如果 grow_size == 0，表示 * 2 增长 */
    int                 grow_size;

    DyBuf() : buf(NULL), buf_size(0)
            , buf_left(0), buf_right(0)
            , grow_size(0)
    {
    }

    DyBuf(int init_size);

    ~DyBuf();

    inline char *get_buf()
    {
        return (buf ? (buf + buf_left) : NULL);
    }

    inline char *get_buf_end()
    {
        return (buf ? (buf + buf_right) : NULL);
    }

    inline int get_size() const { return buf_right - buf_left; }

    inline int get_free_size() const { return buf_size - buf_right; }

    inline int get_mem_size() const { return buf_size; }

    inline void set_grow_size(int size)
    {
        grow_size = (size >= 0) ? size : 0;
    }

    bool append(const void *ptr, int len);

    bool assign(const void *ptr, int len);

    void drop_first(int nbytes);

    void drop_last(int nbytes);

    void move_to_begin();

    bool ensure_size(int len);

    inline void clear()
    {
        buf_left = buf_right = 0;
    }

    void reset_mem();
};

#endif /* _DYBUF_H_ */
